package com.aiti.lulian.gxmh.excel;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.aiti.base.core.exception.BusinessException;
import com.aiti.framework.commons.dictmodel.entity.SysDictData;
import com.aiti.lulian.constant.GxmhConstant;
import com.aiti.lulian.gxmh.entity.GovArticle;
import com.aiti.lulian.gxmh.service.GovArticleManageService;
import com.aiti.lulian.mapper.SysAreaMapper;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * description:
 * auth fcb
 * date 2025-06-18 20:06
 **/
@Slf4j
public class GxmhExcelArticleListener implements ReadListener<GxmhExcelArticleParamDto> {

    private static final int BATCH_COUNT = 200;

    private List<GovArticle> cachedDataList = new ArrayList<>(BATCH_COUNT);

    private GovArticleManageService govArticleManageService;

    private String createBy;

    private DataSourceTransactionManager transactionManager;

    private TransactionStatus transactionStatus = null;

    private SysAreaMapper sysAreaMapper;

    private List<SysDictData> policyTypeList;

    public GxmhExcelArticleListener(GovArticleManageService govArticleManageService, String createBy, DataSourceTransactionManager transactionManager, SysAreaMapper sysAreaMapper, List<SysDictData> policyTypeList) {
        this.govArticleManageService = govArticleManageService;
        this.createBy = createBy;
        this.transactionManager = transactionManager;
        DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        transactionDefinition.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_DEFAULT);
        transactionDefinition.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);
        this.transactionStatus = transactionManager.getTransaction(transactionDefinition);
        this.sysAreaMapper = sysAreaMapper;
        this.policyTypeList = policyTypeList;
    }

    private void saveData() {
        log.info("导入政策{}条数据，开始存储数据库！", cachedDataList.size());
        govArticleManageService.saveBatch(cachedDataList);
        log.info("存储数据库成功！");
    }

    private GovArticle convertData(GxmhExcelArticleParamDto dto) {
        GovArticle article = new GovArticle();
        article.setBaseId(IdUtil.simpleUUID());
        article.setTitle(dto.getTitle());
        article.setBody(dto.getBody());
        for(SysDictData policyType : policyTypeList) {
            if(policyType.getBaseName().equals(dto.getPolicyType())) {
                article.setPolicyType(policyType.getBaseId());
            }
        }
        if(StrUtil.isBlank(dto.getHotEndTime()) && "热门政策".equals(dto.getPolicyType())) {
            throw new BusinessException("热门政策需要设置截止日期");
        }
        article.setLevel(dto.getLevel());
        article.setSource(dto.getSource());
        article.setArticlePublishTime(DateUtil.parse(dto.getArticlePublishTime()));
        if(StrUtil.isNotBlank(dto.getHotEndTime()) && "热门政策".equals(dto.getPolicyType())) {
            article.setHotEndTime(DateUtil.parse(dto.getHotEndTime()));
        }
        String region = dto.getRegion();
        if(StrUtil.isNotBlank(region)) {
            String[] split = region.split("-");
            String city = split[0];
            String county = split[1];
            article.setProvince("F2557678-A421-4E33-9F18-B93FDB3C86DC");
            String cityBaseId = sysAreaMapper.getCityOrCountyBaseId(city, "F2557678-A421-4E33-9F18-B93FDB3C86DC");
            article.setCity(cityBaseId);
            article.setCounty(sysAreaMapper.getCityOrCountyBaseId(county, cityBaseId));
            // 街道
            if(split.length == 3) {
                article.setStreet(sysAreaMapper.getCityOrCountyBaseId(split[2], article.getCounty()));
            }
        }
        article.setArticleType("sys");
        article.setBaseCreateTime(new Date());
        article.setBaseCreateBy(createBy);
        article.setBaseUpdateTime(new Date());
        article.setBaseUpdateBy(createBy);
        article.setIsDelete(0);
        article.setFormId(GxmhConstant.DEFAULT_FORM_ID);
        return article;
    }

    @Override
    public void invoke(GxmhExcelArticleParamDto data, AnalysisContext analysisContext) {
        log.info("解析到一条数据:{}", JSON.toJSONString(data));
        if(StrUtil.isEmpty(data.getTitle())) {
            return;
        }
        cachedDataList.add(this.convertData(data));
        if (cachedDataList.size() >= BATCH_COUNT) {
            this.saveData();
            cachedDataList = new ArrayList<>(BATCH_COUNT);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 如果事务已经提交或回滚
        if (transactionStatus.isCompleted()) {
            return;
        }
        this.saveData();
        if (!transactionStatus.isCompleted()) {
            transactionManager.commit(transactionStatus);
            log.info("当前事务已提交");
        }
        log.info("诉求导入完成！");
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        log.error("导入诉求异常，事务回滚");
        this.transactionManager.rollback(transactionStatus);
        throw exception;
    }

}
